package com.jxpanda.infrastructure.crypto.constant;

import com.jxpanda.infrastructure.crypto.algorithm.signer.HmacSigner;
import com.jxpanda.infrastructure.crypto.algorithm.signer.SignatureSigner;
import com.jxpanda.infrastructure.crypto.key.EcKeyPairProvider;
import com.jxpanda.infrastructure.crypto.key.EdKeyPairProvider;
import com.jxpanda.infrastructure.crypto.key.HmacKeyProvider;
import com.jxpanda.infrastructure.crypto.key.RsaKeyPairProvider;
import com.jxpanda.infrastructure.crypto.key.contract.KeyPairProvider;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import javax.crypto.SecretKey;
import java.security.KeyPair;

public class AlgorithmSign {

    @Getter
    @RequiredArgsConstructor
    public enum HMAC {
        MD5("HmacMD5", 128),
        SHA1("HmacSHA1", 160),
        SHA256("HmacSHA256", 256),
        SHA384("HmacSHA384", 384),
        SHA512("HmacSHA512", 512);

        private final String algorithm;

        private final int keySize;

        public HmacKeyProvider keyProvider() {
            return new HmacKeyProvider(this.algorithm, this.keySize);
        }

        public SecretKey generateKey() {
            return keyProvider().generateKey();
        }

        public HmacSigner.Builder builder() {
            return new HmacSigner.Builder(this);
        }

    }

    public interface Signature {
        String getAlgorithm();

        KeyPairProvider<?> keyProvider();

        default KeyPair generateKey() {
            return keyProvider().generateKey();
        }

        default SignatureSigner.Builder builder() {
            return new SignatureSigner.Builder(this);
        }

    }


    @Getter
    @RequiredArgsConstructor
    public enum RSA implements Signature {
        SHA1_WITH_RSA("SHA1withRSA"),
        SHA256_WITH_RSA("SHA256withRSA"),
        SHA384_WITH_RSA("SHA384withRSA"),
        SHA512_WITH_RSA("SHA512withRSA");
        private final String algorithm;

        public RsaKeyPairProvider keyProvider() {
            return new RsaKeyPairProvider();
        }

    }

    @Getter
    @RequiredArgsConstructor
    public enum EcDSA implements Signature {
        SHA1_WITH_ECDSA("SHA1withECDSA"),
        SHA256_WITH_ECDSA("SHA256withECDSA"),
        SHA384_WITH_ECDSA("SHA384withECDSA"),
        SHA512_WITH_ECDSA("SHA512withECDSA");
        private final String algorithm;

        public EcKeyPairProvider keyProvider() {
            return new EcKeyPairProvider();
        }

    }

    @Getter
    @RequiredArgsConstructor
    public enum EdDSA implements Signature {
        ED25519("Ed25519"),
        ED448("Ed448");
        private final String algorithm;

        public EdKeyPairProvider keyProvider() {
            return new EdKeyPairProvider(this);
        }

    }


}
